home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- * *
- * XRF input file output file [/s] *
- * *
- * Source file name: XRF_V123.C *
- * *
- * DESCRIPTION: *
- * *
- * Cross Reference & Block Structure *
- * Version 1.23 October 10, 1988 *
- * *
- * 'XRF' is a cross-reference block-structure program *
- * written in C for C and similar languages. It has the *
- * following features: *
- * *
- * 1) Single spaced cross-reference list *
- * *
- * 2) Block structure in output program, *
- * nested blocks included *
- * *
- * 3) Removal of tabs in output file as some printers *
- * don't support them *
- * *
- * 4) Strip white space from end of lines in output files *
- * *
- * 5) Works on C or Telix SALT script source files *
- * *
- * *
- * FUNCTIONS: *
- * *
- * Function Description *
- * -------- ----------- *
- * get_token Returns a valid identifier or reserved word. *
- * getch Returns a character from the character buffer *
- * and when ready for new line prints line to file. *
- * ungetch Puts the character optained by getch back in *
- * the character buffer. *
- * getline Gets a line of text from a file, removes tabs, *
- * and removes white space from the end of the line. *
- * ungetline Puts a line of text in the character buffer. *
- * checktoken Compares the token with Beginning and end of *
- * block characters. *
- * in_comment Skips over comments in a file. *
- * in_salt_comment Skips over comments in a SALT file. *
- * in_quote Skips over quotes in a file. *
- * in_salt_quote Skips over quotes in a SALT file. *
- * line_hdr Puts dashes in place of leading blanks on the *
- * front of a line. *
- * block_line_hdr Puts block information in front of the line *
- * and adds a new line to the output file. *
- * page_hdr Puts a header on each page. *
- * type Reutrns the type of character LETTER, DIGIT, *
- * other. *
- * strsave Saves a string in memory. *
- * treex Puts tokens and line numbers in a binary tree. *
- * treexprint Prints out the tree to a file. *
- * add_line_num Puts a linenumber in the tree at the token it *
- * goes with. *
- * treenewline Adds a new line of tree token and numbers to the *
- * output file. *
- * list_alloc Makes space for the linked list. *
- * tree_alloc Makes space for the tree nodes. *
- * *
- ****************************************************************************
- * *
- * Revision history: *
- * *
- * v1.00 by Jay B. Bronaugh - 10/12/87 *
- * for C Programming class @ Phoenix College *
- * only exists as photocopied listing *
- * original name CCR *
- * *
- * v1.01 by Tom Goodgame - 09/25/88 *
- * typed in from listing using personal style *
- * changed declaration of character variables from int to char *
- * *
- * v1.10 by Tom Goodgame - 09/26/88 *
- * added code to allow use on Telix v3.0 SALT scripts *
- * modified get_token, added in_salt_comment & in_salt_quote *
- * added code for output to test file during debugging *
- * currently commented out *
- * *
- * v1.20 by Tom Goodgame - 09/27/88 *
- * change user interface so that USAGE line is shown when there *
- * are no parameters supplied, instead of prompting for the *
- * file names *
- * add sensing of command line switches, first switch to be *
- * added will be for indicating that input file is a Telix *
- * SALT script (instead of relying on detection of SALT type *
- * comments) *
- * fixed ALL compiler warnings *
- * Added BOOLEAN type for flags (specialized int) in boolean.h *
- * *
- * v1.21 by Tom Goodgame - 09/28/88 *
- * bug created by overchecking comment syntax caused "syntax" *
- * error when faced with a divide (i.e., x/y) *
- * *
- * v1.22 by Tom Goodgame - 10/02/88 *
- * change appearance of Copyright notice *
- * improved variable naming *
- * improved message text from errors *
- * changed test for /s switch so it looked for both upper and *
- * lower case 's'. *
- * *
- * v1.23 by Tom Goodgame - 10/10/88 *
- * get version number correct in USAGE output *
- * *
- * Planned for version 1.30 is auto line wrap. Currently lines can *
- * be 256 characters long and there is no attempt to wrap them. The *
- * program was originally written around a 132 character printer *
- * width. Input lines greater than 80 characters will run off the *
- * edge of the paper or be wrapped by the printer. *
- * *
- * Planned for v2.xx will be parameter files for syntax, keywords, *
- * etc. with a different set for each language so the program will *
- * be useable with any language and keywords will be separated *
- * from functions and variables. *
- * *
- ****************************************************************************
- * *
- * Copyright (C) 1988 by Thomas H. Goodgame, Jr. - all rights reserved *
- * *
- * Source code and executable modules are freely useable and *
- * distributable, subject to the following five conditions: *
- * *
- * 1) If they are included with a commercial package, no changes *
- * may be made to the source, they must be distributed in their *
- * entirety, and no charge can be made for these programs. *
- * *
- * 2) If they are distributed by a public domain/freeware/shareware *
- * distribution organization (PC-SIG, user group, etc.) the *
- * charge per diskette of programs must not exceed six dollars *
- * ($6). All files must be distributed together on one disk and *
- * preferably in one library or archive file. *
- * *
- * 3) If they are distributed by BBS, no additional charges above *
- * and beyond the connection charge (if any) may be made. All *
- * files must be distributed together in one library or archive *
- * file. *
- * *
- * 4) Individuals and educational institutions may distribute these *
- * programs without charge. They may also modify the source for *
- * their purposes so long as attribution is made. They should *
- * also indicate what the changes were, whom by, and the date. *
- * Copyright should be asserted to prevent the code from going *
- * public domain and then being commercialized. *
- * *
- * 5) Any other distribution not directly covered, must be made in *
- * the spirit of the above conditions. *
- * *
- * Contact: Tom Goodgame via CompuServe UserID 76327,2053 *
- * *
- * or *
- * *
- * Tom Goodgame via Flying Circus BBS (602) 437-1301 *
- * CentraLink BBS (602) 254-9031 *
- * Inn on the Park BBS (602) 957-0631 *
- * ASU Underground BBS (602) 968-2814 *
- * Tool Shop BBS (602) 279-2673 *
- * *
- * or *
- * *
- * Thomas Goodgame via Phoenix PCUG BBS (602) 275-5558 *
- * *
- * *
- ****************************************************************************/
-
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <boolean.h>
-
- /*************
- * constants *
- *************/
-
- #define TAB_SPACE 8
- #define LETTER 'a'
- #define DIGIT '0'
- #define MAX_WORD_LENGTH 32
- #define FORM_FEED '\014'
- #define PRINT_LINES 52
- #define MAX_NUM_BLOCKS 20
- #define MAX_LINE_LENGTH 256
- #define BUFFER_SIZE 256
- #define PROGNAME "Cross Reference & Block Structure"
- #define COPYRIGHT "Copyright (C) 1988 by Thomas H. Goodgame, Jr. \
- - all rights reserved"
- #define VERSION "ver 1.23"
- #define VER_DATE "10/10/1988"
-
- /**************
- * structures *
- **************/
-
- struct linklist
- {
- int lnum;
- struct linklist *ptr;
- };
-
- struct tnode
- {
- char *word;
- struct linklist *lines;
- struct tnode *left;
- struct tnode *right;
- };
-
- /********************
- * global variables *
- ********************/
-
- FILE *infile;
- FILE *outfile;
- /* FILE *tstfile; */
-
- char inname[MAX_LINE_LENGTH];
- char outname[MAX_LINE_LENGTH];
- /* char tstname[] = "test.fil"; */
-
- char sw_strn[MAX_LINE_LENGTH];
- char line[MAX_LINE_LENGTH];
-
- BOOLEAN is_salt = FALSE; /* File is a Telix SALT script */
- BOOLEAN switches = FALSE; /* Switch argument supplied */
-
- char buffer[BUFFER_SIZE];
- int buffer_position = 0;
- int line_number = 0;
- int token_number = 0;
- int page_number = 0;
- int blocks = 0;
- int totalblocks = 0;
- int blocknest = 0;
- char block = ' ';
-
- /***********************
- * function prototypes *
- ***********************/
-
- int getline(char *, int);
- void ungetch(char);
- void ungetline(char []);
- void line_hdr(char *);
- void block_line_hdr(void);
- void page_hdr(void);
- char getch(void);
- int type(char);
- void in_comment(void);
- void in_salt_comment(void);
- void in_quote(char);
- void in_salt_quote(char);
- void checktoken(char *);
- int get_token(char *, int);
- struct linklist *list_alloc(void);
- struct tnode *tree_alloc(void);
- char *strsave(char *);
- void add_line_num(struct tnode *, int);
- struct tnode *treex(struct tnode *, char *, int);
- void treenewline(void);
- void treexprint(struct tnode *);
- int main(int, char * []);
-
- /***********
- * getline *
- ***********/
-
- int getline(s, lim)
- char *s;
- int lim;
- {
- int c;
- int nb = 0;
- int pos = 1;
-
- while (--lim > 0 && (c = getc(infile)) != EOF && c != '\n')
- if (c == '\t')
- {
- nb = TAB_SPACE - (pos - 1) % TAB_SPACE;
- while (nb > 0)
- {
- *s++ = ' ';
- ++pos;
- --nb;
- }
- }
- else
- {
- *s++ = (char)c;
- ++pos;
- }
- if (lim == 0)
- {
- fprintf(stderr, "FATAL ERROR: Line longer than %d characters\n",
- MAX_LINE_LENGTH);
- exit(1);
- }
- *s--;
- if (*s == ' ')
- {
- while (*s == ' ')
- *s--;
- *s--;
- *s++;
- }
- *s++;
- *s++ = (char)c;
- *s = NULL;
- if (c == EOF)
- return(EOF);
- return(0);
- }
-
- /***********
- * ungetch *
- ***********/
-
- void ungetch(c)
- char c;
- {
- if (buffer_position > BUFFER_SIZE)
- {
- fprintf(stderr, "FATAL ERROR: Buffer overflow\n");
- exit(1);
- }
- else
- buffer[buffer_position++] = c;
- }
-
- /*************
- * ungetline *
- *************/
-
- void ungetline(s)
- char s[];
- {
- int len = strlen(s);
-
- while (len > 0)
- ungetch(s[--len]);
- }
-
- /************
- * line_hdr *
- ************/
-
- void line_hdr(s)
- char *s;
- {
- char c;
-
- while (*s == ' ')
- if (*s == ' ')
- *s++ = '-';
- }
-
- /******************
- * block_line_hdr *
- ******************/
-
- void block_line_hdr()
- {
- int blk;
-
- fprintf(outfile, "%4d ", line_number);
- printf("%4d\r", line_number);
- switch (block)
- {
- case 'S' :
- for (blk = 0; blk < blocks; ++blk)
- fprintf(outfile, "| ");
- fprintf(outfile, "%c", block);
- for (blk = 0; blk < (MAX_NUM_BLOCKS - blocks); ++blk)
- fprintf(outfile, "--");
- blocks += (blocknest - blocks);
- block = ' ';
- line_hdr(line);
- break;
- case 'E' :
- blocks += (blocknest - blocks);
- for (blk = 0; blk < blocks; ++blk)
- fprintf(outfile, "| ");
- fprintf(outfile, "%c", block);
- for (blk = 0; blk < (MAX_NUM_BLOCKS - blocks); ++blk)
- fprintf(outfile, "--");
- block = ' ';
- line_hdr(line);
- break;
- default :
- for (blk = 0; blk < blocks; ++blk)
- fprintf(outfile, "| ");
- fprintf(outfile, "%c", block);
- for (blk = 0; blk < (MAX_NUM_BLOCKS - blocks); ++blk)
- fprintf(outfile, " ");
- }
- }
-
- /************
- * page_hdr *
- ************/
-
- void page_hdr()
- {
- fprintf(outfile, "\%c", FORM_FEED);
- fprintf(outfile, "\n\n\n\n\n\n");
- fprintf(outfile, " \%-12s", inname);
- fprintf(outfile, " ");
- fprintf(outfile, "%s %s", PROGNAME, VERSION);
- fprintf(outfile, " ");
- fprintf(outfile, "Page %4d\n\n", ++page_number);
- }
-
- /*********
- * getch *
- *********/
-
- char getch()
- {
- if (buffer_position > 0)
- return(buffer[--buffer_position]);
- else
- {
- if (line_number != 0)
- block_line_hdr();
- fprintf(outfile, "%s", line);
- if ((line_number % PRINT_LINES) == 0)
- page_hdr();
- if ((getline(line, MAX_LINE_LENGTH)) != EOF)
- line_number++;
- ungetline(line);
- return(getch());
- }
- }
-
- /********
- * type *
- ********/
-
- int type(c)
- char c;
- {
- if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '_')
- return(LETTER);
- else if (c >= '0' && c <= '9')
- return(DIGIT);
- else
- return(c);
- }
-
- /**************
- * in_comment *
- **************/
-
- void in_comment()
- {
- char c, ch;
-
- c = getch();
- ch = getch();
- while (c != '*' || ch != '/')
- {
- c = ch;
- ch = getch();
- }
- }
-
- /*******************
- * in_salt_comment *
- *******************/
-
- void in_salt_comment()
- {
- char c;
-
- c = getch();
- while (c != '\n')
- {
- c = getch();
- }
- ungetch(c);
- }
-
- /************
- * in_quote *
- ************/
-
- void in_quote(c)
- char c;
- {
- char ch;
-
- while ((ch = getch()) != c)
- if (ch == '\\')
- getch();
- }
-
- /*****************
- * in_salt_quote *
- *****************/
-
- void in_salt_quote(c)
- char c;
- {
- char ch;
-
- while ((ch = getch()) != c);
- }
-
- /**************
- * checktoken *
- **************/
-
- void checktoken(t)
- char *t;
- {
- if (strcmp(t, "{") == 0)
- {
- block = 'S';
- blocknest++;
- totalblocks++;
- }
- if (strcmp(t, "}") == 0)
- {
- block = 'E';
- blocknest--;
- }
- }
-
- /*************
- * get_token *
- *************/
-
- int get_token(w, lim)
- char *w;
- int lim;
- {
- char c;
- int t;
-
- if ((t = type(c = *w++ = getch())) != LETTER)
- {
- if (c == '/')
- {
- c = getch();
- if (c == '*'&& is_salt == FALSE)
- in_comment();
- else if (c == '/' && is_salt == TRUE)
- in_salt_comment();
- else if (c == '*' && is_salt == TRUE || c == '/' && is_salt == FALSE)
- {
- fprintf(stderr, "FATAL ERROR: Improper comment syntax, line = %4d\n",
- line_number);
- exit(5);
- }
- }
- if (c == '\'' || c == '\"')
- if (is_salt == TRUE)
- in_salt_quote(c);
- else
- in_quote(c);
- *w = '\0';
- return(c);
- }
- while (--lim > 0)
- {
- t = type(c = *w++ = getch());
- if (t != LETTER && t != DIGIT)
- {
- ungetch(c);
- break;
- }
- }
- *(w-1) = '\0';
- return(LETTER);
- }
-
- /**************
- * list_alloc *
- **************/
-
- struct linklist *list_alloc()
- {
- return((struct linklist *) malloc(sizeof(struct linklist)));
- }
-
- /**************
- * tree_alloc *
- **************/
-
- struct tnode *tree_alloc()
- {
- return((struct tnode *) malloc(sizeof(struct tnode)));
- }
-
- /***********
- * strsave *
- ***********/
-
- char *strsave(s)
- char *s;
- {
- char *p;
-
- if ((p = malloc(strlen(s) + 1)) != NULL)
- strcpy(p, s);
- return(p);
- }
-
- /****************
- * add_line_num *
- ****************/
-
- void add_line_num(p, line_number)
- struct tnode *p;
- int line_number;
- {
- struct linklist *temp, *list_alloc();
-
- temp = p -> lines;
- while (temp -> ptr != NULL && temp -> lnum != line_number)
- temp = temp -> ptr;
- if (temp -> lnum != line_number)
- {
- temp -> ptr = list_alloc();
- temp -> ptr -> lnum = line_number;
- temp -> ptr -> ptr = NULL;
- }
- }
-
- /*********
- * treex *
- *********/
-
- struct tnode *treex(p, w, line_number)
- struct tnode *p;
- char *w;
- int line_number;
- {
- struct tnode *tree_alloc();
- struct linklist *list_alloc();
- char *strsave();
- int cond;
-
- if (p == NULL)
- {
- p = tree_alloc();
- p -> word = strsave(w);
- p -> lines = list_alloc();
- p -> lines -> lnum = line_number;
- p -> lines -> ptr = NULL;
- p -> left = p -> right = NULL;
- }
- else if ((cond = strcmp(w, p -> word)) == 0)
- add_line_num(p, line_number);
- else if (cond > 0)
- p -> left = treex(p -> left, w, line_number);
- else
- p -> right = treex(p -> right, w, line_number);
- return(p);
- }
-
- /***************
- * treenewline *
- ***************/
-
- void treenewline()
- {
- ++token_number;
- fprintf(outfile, "\n");
- if ((token_number % PRINT_LINES) == 0)
- page_hdr();
- }
-
- /**************
- * treexprint *
- **************/
-
- void treexprint(p)
- struct tnode *p;
- {
- struct linklist *temp;
- int dots, num, gap;
-
- if (p != NULL)
- {
- treexprint(p -> right);
- fprintf(outfile, "%s", p -> word);
- for (dots = 0; dots < (MAX_WORD_LENGTH - (strlen(p -> word))); dots++)
- fprintf(outfile, ".");
- for (temp = p -> lines, num = 1; temp != NULL; temp = temp -> ptr, ++num)
- {
- fprintf(outfile, " %4d ", temp -> lnum);
- if ((num % 16) == 0)
- {
- treenewline();
- for (gap = 0; gap < MAX_WORD_LENGTH; gap++)
- fprintf(outfile, " ");
- }
- }
- treenewline();
- treexprint(p -> left);
- }
- }
-
- /********
- * main *
- ********/
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- struct tnode *root, *treex();
- char word[MAX_WORD_LENGTH];
- int t;
-
- fprintf(stderr, "%s %s %-10s\n", PROGNAME, VERSION,
- VER_DATE);
- fprintf(stderr, " %s\n\n", COPYRIGHT);
-
- if (argc >= 3)
- {
- strcpy(inname, argv[1]);
- strcpy(outname, argv[2]);
- }
- else
- {
- fprintf(stderr, "\n");
- fprintf(stderr, " USAGE: XRF [input file] [output file] /switch(es)\n");
- fprintf(stderr, " [input file] required\n");
- fprintf(stderr, " [output file] required\n");
- fprintf(stderr, " /switch(es) optional\n");
- fprintf(stderr, " /s - input file is Telix SALT script\n");
- fprintf(stderr, "\n");
- fprintf(stderr, " ERRORLEVEL return codes:\n");
- fprintf(stderr, " 0 - successful\n");
- fprintf(stderr, " 1 - line too long or buffer overflow\n");
- fprintf(stderr, " 2 - could not open file\n");
- fprintf(stderr, " 3 - input and output files the same\n");
- fprintf(stderr, " 4 - no arguments supplied (produced this screen)\n");
- fprintf(stderr, " 5 - improper comment syntax\n");
- fprintf(stderr, "\n");
- exit(4);
- }
-
-
- if (argc > 4)
- fprintf(stderr, "NON-FATAL ERROR: Excess arguments suppled on command line"
- " were ignored");
-
- if (argc >= 4)
- {
- strcpy(sw_strn, argv[3]);
- switches = TRUE;
- }
-
- if (switches == TRUE)
- if (strlen(sw_strn) == 2)
- if (strstr(sw_strn, "/s") != NULL || strstr(sw_strn, "/S") != NULL)
- is_salt = TRUE;
- else
- fprintf(stderr, "NON-FATAL ERROR: Undefined switch %s entered - "
- "ignored\n", sw_strn);
- else
- fprintf(stderr,
- "NON-FATAL ERROR: Switch argument not correct length - ignored\n");
-
- if (strcmp(inname, outname) == 0)
- {
- fprintf(stderr, "FATAL ERROR: Input and output files can't be the same\n");
- exit(3);
- }
-
- if ((infile = fopen(inname, "r")) == NULL)
- {
- fprintf(stderr, "FATAL ERROR: Unable to open input file %s\n", inname);
- exit(2);
- }
-
- if ((outfile = fopen(outname, "w")) == NULL)
- {
- fprintf(stderr, "FATAL ERROR: Unable to open output file %s\n", outname);
- fclose(infile);
- exit(2);
- }
-
- /*
- if ((tstfile = fopen(tstname, "w")) == NULL)
- {
- fprintf(stderr, "FATAL ERROR: Unable to open test file %s\n", tstname);
- fclose(infile);
- fclose(outfile);
- exit(2);
- }
- */
-
- printf("\nReading from %s\n", inname);
- printf(" Lines\r");
-
- root = NULL;
- while ((t = get_token(word, MAX_WORD_LENGTH)) != EOF)
- {
- checktoken(word);
- if (t == LETTER)
- root = treex(root, word, line_number);
- }
-
- page_hdr();
- printf("\n\nWriting to %s\n", outname);
- treexprint(root);
- fprintf(outfile, "\%c", FORM_FEED);
- fclose(infile);
- fclose(outfile);
- /*
- fclose(tstfile);
- */
- printf("%4d Lines\n", (line_number + token_number));
- printf("%4d References\n", token_number);
- printf("%4d Blocks\n", totalblocks);
- printf("%4d Pages\n", page_number);
- exit(0);
- return(0);
- }
-
-